package com.xh3140.android.widget.sliderbar;

import android.content.Context;
import android.graphics.Paint;
import android.graphics.RectF;
import android.util.AttributeSet;
import android.view.View;

import androidx.annotation.ColorInt;
import androidx.annotation.Nullable;
import androidx.annotation.Px;
import androidx.annotation.Size;

@SuppressWarnings("unused")
public abstract class AbstractSliderBar extends View {
    // 范围下限
    protected float mRangeLower = 0f;

    // 范围上限
    protected float mRangeUpper = 100f;

    // 滑条厚度，px
    @Px
    protected int mSliderStripThickness = 5;

    // 滑条圆角半径，px
    @Px
    protected int mSliderStripRadius = 0;

    // 滑条颜色，argb
    @ColorInt
    protected int mSliderStripColor = 0xFFDCDCDC;

    // 滑块颜色，argb
    @ColorInt
    protected int mSliderBlockColor = 0xFFFF4500;

    // 滑块半径，px
    @Px
    protected int mSliderBlockRadius = 15;

    // 固有内边距，px
    @Size(4)
    protected final int[] mInnatePadding = {10, 10, 10, 10};

    // 滑条区域
    protected final RectF mSliderStripRectF = new RectF(0f, 0f, 0f, 0f);

    // 画笔
    protected final Paint mPaint = new Paint(Paint.ANTI_ALIAS_FLAG);

    // 滑条宽度，px
    protected int mSliderStripWidth = 0;

    // 滑块纵坐标
    protected int mSliderBlockCenter = 0;

    public AbstractSliderBar(Context context) {
        super(context);
    }

    public AbstractSliderBar(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
    }

    public AbstractSliderBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, defStyleAttr);
    }

    public AbstractSliderBar(Context context, @Nullable AttributeSet attrs, int defStyleAttr, int defStyleRes) {
        super(context, attrs, defStyleAttr, defStyleRes);
    }

    protected float v2d(float value) {
        return mSliderStripWidth * value / (mRangeUpper - mRangeLower);
    }

    protected float d2v(float distance) {
        return (mRangeUpper - mRangeLower) * distance / mSliderStripWidth;
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        super.onMeasure(widthMeasureSpec, heightMeasureSpec);
        final int widthMode = MeasureSpec.getMode(widthMeasureSpec);
        final int widthSize = MeasureSpec.getSize(widthMeasureSpec);
        final int heightMode = MeasureSpec.getMode(heightMeasureSpec);
        final int heightSize = MeasureSpec.getSize(heightMeasureSpec);
        int measuredWidth = widthSize;
        int measuredHeight = heightSize;
        if (widthMode == MeasureSpec.AT_MOST) {
            // 滑条宽度默认120dp
            final int sliderStripWidth = (int) (120 * getResources().getDisplayMetrics().density + 0.5f);
            measuredWidth = getPaddingStart() + getPaddingEnd() + sliderStripWidth + mInnatePadding[0] + mInnatePadding[2];
        }
        if (heightMode == MeasureSpec.AT_MOST) {
            measuredHeight = getPaddingTop() + getPaddingBottom() + 2 * mSliderBlockRadius + mInnatePadding[1] + mInnatePadding[3];
        }
        setMeasuredDimension(measuredWidth, measuredHeight);
    }

    @Override
    protected void onLayout(boolean changed, int left, int top, int right, int bottom) {
        super.onLayout(changed, left, top, right, bottom);
        // 滑条区域
        mSliderStripRectF.left = getPaddingStart() + mSliderBlockRadius + mInnatePadding[0];
        mSliderStripRectF.right = getWidth() - getPaddingEnd() - mSliderBlockRadius - mInnatePadding[2];
        mSliderStripRectF.top = getPaddingTop() + (mSliderBlockRadius - mSliderStripThickness / 2f) + mInnatePadding[1];
        mSliderStripRectF.bottom = getHeight() - getPaddingBottom() - (mSliderBlockRadius - mSliderStripThickness / 2f) - mInnatePadding[3];
        mSliderStripRectF.top = Math.max(mSliderStripRectF.top, getHeight() / 2f - mSliderStripThickness / 2f);
        mSliderStripRectF.bottom = Math.min(mSliderStripRectF.bottom, getHeight() / 2f + mSliderStripThickness / 2f);
        // 滑条宽度
        mSliderStripWidth = (int) (mSliderStripRectF.right - mSliderStripRectF.left);
        // 滑块纵坐标
        mSliderBlockCenter = (int) ((mSliderStripRectF.top + mSliderStripRectF.bottom) / 2);
    }

    /**
     * 判断值在范围内
     *
     * @param value 被判断的值
     */
    public boolean isInRange(float value) {
        return value >= mRangeLower && value <= mRangeUpper;
    }

    /**
     * 约束值在范围内
     *
     * @param value 被约束的值
     */
    public float constraintInRange(float value) {
        return Math.max(mRangeLower, Math.min(value, mRangeUpper));
    }

    /**
     * 获取范围下限
     */
    public float getRangeLower() {
        return mRangeLower;
    }

    /**
     * 获取范围上限
     */
    public float getRangeUpper() {
        return mRangeUpper;
    }

    /**
     * 设置范围上限
     * 注意：这个值在不超过范围上限时才有效
     *
     * @param lower 下限
     */
    public void setRangeLower(float lower) {
        if (mRangeLower != lower && mRangeLower <= mRangeUpper) {
            mRangeLower = lower;
            invalidate();
        }
    }

    /**
     * 设置范围上限
     * 注意：这个值在不低于范围下限时才有效
     *
     * @param upper 上限
     */
    public void setRangeUpper(float upper) {
        if (mRangeUpper != upper && mRangeUpper >= mRangeLower) {
            mRangeUpper = upper;
            invalidate();
        }
    }

    /**
     * 设置范围上限
     *
     * @param lower 下限
     * @param upper 上限
     */
    public void setRange(float lower, float upper) {
        if (lower <= upper) {
            mRangeLower = lower;
            mRangeUpper = upper;
            invalidate();
        }
    }

    /**
     * 设置滑条厚度，px
     */
    public void setSliderStripThickness(@Px int thickness) {
        if (mSliderStripThickness != thickness) {
            mSliderStripThickness = thickness;
            requestLayout();
            invalidate();
        }
    }

    /**
     * 滑条圆角半径，px
     */
    public void setSliderStripRadius(@Px int radius) {
        if (mSliderStripRadius != radius) {
            mSliderStripRadius = radius;
            requestLayout();
            invalidate();
        }
    }

    /**
     * 设置滑条颜色，argb
     */
    public void setSliderStripColor(@ColorInt int color) {
        if (mSliderStripColor != color) {
            mSliderStripColor = color;
            invalidate();
        }
    }

    /**
     * 设置滑块颜色 argb
     */
    public void setSliderBlockColor(@ColorInt int color) {
        if (mSliderBlockColor != color) {
            mSliderBlockColor = color;
            invalidate();
        }
    }

    /**
     * 设置滑块半径 px
     */
    public void setSliderBlockRadius(@Px int radius) {
        if (mSliderBlockRadius != radius) {
            mSliderBlockRadius = radius;
            requestLayout();
            invalidate();
        }
    }
}
